home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 19 / CD_ASCQ_19_010295.iso / dos / prg / pas / swag / oop.swg / 0040_TV Library Objects.pas < prev    next >
Pascal/Delphi Source File  |  1994-05-26  |  51KB  |  1,183 lines

  1. Unit Misc;
  2.  
  3. {
  4.                                 MISC.PAS
  5.                      A Turbo Vision Object Library
  6.  
  7.                              By  Devin Cook
  8.                                MSD - 1990
  9.  
  10. I haven't been exactly overwhelmed by the amount of Turbo Vision objects shared
  11. by TP users, so I thought I would thow my hat into the ring and spread a few
  12. objects I have developed around.
  13.  
  14. I am not an expert in Turbo Vision ( who can be in 3 weeks? ), or in OOP, so I
  15. have probably broken quite a few rules, but you might get some ideas from the
  16. work I have done.
  17.  
  18. This unit has some of the my more mainstream objects included.  I have a few
  19. other, less general objects which I may spread around later.
  20.  
  21. These objects have not been used enough to verify they are 100% bug free, so
  22. if you find any problems, or have any comments, please send me some Email
  23. ( D.Cook on Genie ).
  24.  
  25.                                 OBJECTS:
  26.  
  27. TDateView      -    A date text box, much like TClockView in TVDemos.
  28.  
  29. TPushButton    -    A descendend of TButton, with "feel" for keyboard users.
  30.  
  31. TNum_Box       -    A number only input box with an adjustable number of digits
  32.                     before and after the decimal point, along with selectable
  33.                     negative number acceptance.
  34.  
  35. TLinked_Dialog -    A descendent of TDialog which allows you to set "Links"
  36.                     between items ( i.e. item selection through cursor keys ).
  37.  
  38. Also, FormatDate, a function used by TDateView is provided.
  39.  
  40.  
  41.                             ╔═════════════╗
  42.                             ║  TDateView  ║
  43.                             ╚═════════════╝
  44.  
  45.  
  46. TDateView is almost identicle to TClockView ( in TVDemos - Gadget.Pas ).
  47.  
  48. INITIALIZATION:
  49.  
  50. TDateView is initialized by sending TDateView a TRect giving it's location.
  51.  
  52. USAGE:
  53.  
  54. Once TDateView is initialized, an occasional call to TDateView.Update keeps
  55. the displayed date current.
  56.  
  57. Example:
  58.  
  59.   Var TR    : TRect ;
  60.       DateV : TDateView ;
  61.   Begin
  62.       TR.Assign( 60 , 0 , 78 , 1 );
  63.       DateV.Init( TR );
  64.       DateV.Update ;
  65.   End;
  66.  
  67.  
  68.  
  69.                            ╔═══════════════╗
  70.                            ║  TPushButton  ║
  71.                            ╚═══════════════╝
  72.  
  73.  
  74. TPushButton is identicle to TButton in every way except that when it is
  75. "pressed", it actually draws itself pressed.
  76.  
  77. This gives visual feedback to those using non-mouse systems.
  78.  
  79. The delay values in TPushButton.Press may need to be altered to adjust the
  80. "feel".
  81.  
  82.                              ╔════════════╗
  83.                              ║  TNum_Box  ║
  84.                              ╚════════════╝
  85.  
  86.  
  87. TNum_Box is a numerical entry box with definable precision.
  88.  
  89. INITIALIZATION:
  90.  
  91. TNum_Box is initialized by sending TNum_Box.Init:
  92.         Location                            : TPoint
  93.         Max Digits before the decimal point : Integer
  94.         Max Digits after the decimal point  : Integer
  95.         Negative Numbers allowed flag       : Boolean
  96.         Default Value                       : Extended
  97.  
  98. If the digits after the decimal point = 0, no decimal point is displayed
  99. ( or excepted ).
  100.  
  101. If negative numbers are allowed, one extra space is reserved for a negative
  102. sign.  No digits can be entered in this spot.
  103.  
  104. Only Backspace is used to edit the numberical field.
  105.  
  106. USAGE:
  107.  
  108. The value of the input box can be read directly from TNum_Box.Curr_Val.
  109.  
  110. This value may not be up to date if editing is still taking place, or no
  111. data has been entered.  To ensure a correct reading, a call to
  112. TNum_Box.Update_Value is recommended.
  113.  
  114. After initilization, the box is displayed with blanks for the number of digits.
  115. If you wish to display the default value instead, use TNum_Box.Update_Value.
  116.  
  117. Example:
  118.  
  119.   Var TP        : TPoint ;
  120.       Int_Box1  : TNum_Box ;
  121.       Int_Box2  : TNum_Box ;
  122.       Flt_Box1  : TNum_Box ;
  123.   Begin
  124.       Tp.X := 10 ;
  125.       Tp.Y := 5 ;
  126.  
  127.       (* Define a box at 10,5 with 3 digits, no decimals, no negatives and a
  128.          default of 0 *)
  129.  
  130.       Int_Box1.Init( TP , 3 , 0 , False , 0 )
  131.  
  132.       TP.X := 15 ;
  133.  
  134.       (* Define a box at 10,15 with 5 digits, no decimals, negatives and a
  135.          default of 1.  Then, update the box displaying the default *)
  136.  
  137.       Int_Box2.Init( TP , 5 , 0 , True , 1 )
  138.       Int_Box2.Update_Value ;
  139.  
  140.       TP.X := 25 ;
  141.  
  142.       (* Define a box at 10,25 with 5 digits, 2 decimal places , negatives and
  143.          a default of 0.  Leave the box a blank. *)
  144.  
  145.       flt_Box1.Init( TP , 5 , 2 , True , 0 )
  146.  
  147.   End;
  148.  
  149.                           ╔══════════════════╗
  150.                           ║  TLinked_Dialog  ║
  151.                           ╚══════════════════╝
  152.  
  153.  
  154. TLinked_Dialog is descendant of TDialog with improved cursor movement between
  155. fields.
  156.  
  157. Developing for a non-mouse system ( even a mouse system ) where your dialogs
  158. have over about 10 fields gets a bit ugly.  The tab key becomes impracticle
  159. and setting hotkeys for each field may not be practicle.
  160.  
  161. The program EXAMPLE.PAS is not an exageration, it is a SIMPLIFIED version of
  162. a dialog I am developing at work.  Try getting to a field #54 via tabs!
  163.  
  164. TLinked_Dialog solves the problem by having the Dialog jump between links
  165. you define. Cursor keys are used to select the link direction, though 2 spare
  166. links are defined for object future use or for object use.
  167.  
  168.      Example of a linking:               11
  169.                                          21 22
  170.                                          31
  171.  
  172.   Object 21 would want links defined for 11 ( DLink_Up ), 22 ( DLink_Right ),
  173.   and 31 ( DLink_Down ).
  174.  
  175.   Once the links are defined, HandleEvent switches the focus according to the
  176.   cursor keys.
  177.  
  178.  
  179. INITIALIZATION:
  180.  
  181. TDialog is initialized exactly the same as TDialog.  ( Refer to the Turbo Vision
  182. manual for details. )
  183.  
  184. TLinked_Dialog.Init calls TDialog.Init and the initialized a collection of
  185. links to track item linking.
  186.  
  187. USAGE:
  188.  
  189. Once TLinked_Dialog is initialized, you insert items into the TLinked_Dialog
  190. just as you would a normal dialog.
  191.  
  192. After the items are inserted, you set up links.
  193.  
  194. *****  NOTE:  Do not set up links for an item before it is inserted! *****
  195.  
  196. Links are created by calling TLinked_Dialog.Set_Link with
  197.         Item to set link for    : PView
  198.         Direction of link       : Integer
  199.                                               Use the constants:
  200.                                       DLink_Up, Dlink_Down, DLink_Right,
  201.                                       DLink_Left, DLink_Spare1, Dlink_Spare2
  202.         Pointer to linked item  : Pointer
  203.  
  204. All links are 1 way.  If you wish Button55 <--> Button56, you must define
  205. two links, Button55 right to Button56 and Button56 left to Button55.  This is
  206. because multiple items may be linked to the same item, which would make finding
  207. the reverse link impossible.
  208.  
  209. You can select another object via a link by calling TLinked_Dialog.Select_Link
  210. with the link direction.  The currently selected object's link will be traced
  211. to the next object ( If possible ).
  212.  
  213. Example:
  214.  
  215.   Var TR    : TRect ;
  216.       TP    : TPoint ;
  217.       TLD   : TLinked_Dialog ;
  218.       Butt1 : TPushButton ;
  219.       Box1  : TNum_Box ;
  220.       Box2  : TNum_Box ;
  221.       Box3  : TNum_Box ;
  222.       Box4  : TNum_Box ;
  223.  
  224.   Begin
  225.       TR.Assign( 10 , 1 , 70 , 10 );
  226.       TLD.Init( TR ,'Test Linked Dialog');
  227.  
  228.  
  229.       (* Set up a button and insert it *)
  230.  
  231.       TR.Assign( 5 , 3 , 15 , 5 );
  232.       Butt1.Init(TR,'~P~ush',cmOk,bfDefault));
  233.       TLD.Insert( Butt1 );
  234.  
  235.       (* Set up box1 and insert it *)
  236.       TP.Y := 8 ;
  237.       TP.X := 3 ;
  238.  
  239.       Box1.Init( TP , 3 , 2 , FALSE , 1 );
  240.       TLD.Insert( Box1 );
  241.  
  242.       (* Set up box2 and insert it *)
  243.       TP.X := TP.X + 10 ;
  244.  
  245.       Box2.Init( TP , 3 , 2 , FALSE , 1 );
  246.       TLD.Insert( Box2 );
  247.  
  248.       TP.Y := 9 ;
  249.       TP.X := 3 ;
  250.  
  251.       (* Set up box3 and insert it *)
  252.  
  253.       Box3.Init( TP , 3 , 2 , FALSE , 1 );
  254.       TLD.Insert( Box3 );
  255.  
  256.       TP.X := TP.X + 10 ;
  257.  
  258.       (* Set up box and insert it *)
  259.  
  260.       Box4.Init( TP , 3 , 2 , FALSE , 1 );
  261.       TLD.Insert( Box4 );
  262.  
  263.       (*   Boxes at  [1] [2]  *)
  264.       (*             [3] [4]  *)
  265.  
  266.       (* Link Box1 -> Box2 *)
  267.       TDL.Set_Link( @BOX1 , DLink_Right , @BOX2 );
  268.  
  269.       (* Link Box1 <- Box2 *)
  270.       TDL.Set_Link( @BOX2 , DLink_Left  , @BOX1 );
  271.  
  272.       (* Link Box3 -> Box4 *)
  273.       TDL.Set_Link( @BOX3 , DLink_Right , @BOX4 );
  274.  
  275.       (* Link Box3 <- Box4 *)
  276.       TDL.Set_Link( @BOX4 , DLink_Left  , @BOX3 );
  277.  
  278.       (* Link Box1 -> Box3 *)
  279.       TDL.Set_Link( @BOX1 , DLink_Down  , @BOX3 );
  280.  
  281.       (* Link Box1 <- Box3 *)
  282.       TDL.Set_Link( @BOX3 , DLink_Up    , @BOX1 );
  283.  
  284.       (* Link Box2 -> Box4 *)
  285.       TDL.Set_Link( @BOX2 , DLink_Down  , @BOX4 );
  286.  
  287.       (* Link Box2 <- Box4 *)
  288.       TDL.Set_Link( @BOX4 , DLink_Up    , @BOX2 );
  289.  
  290. End;
  291.  
  292.  
  293. }
  294.  
  295. { Note:  Tab Size = 4 }
  296.  
  297. (* Set conditions to allow for "Extended" type *)
  298. {$N+,E+}
  299.  
  300. (**************************************************************************)
  301. (*                                                                        *)
  302. (*               Library of objects for Turbo Vision  V1.00               *)
  303. (*                                                                        *)
  304. (*               By:   Devin Cook                                         *)
  305. (*                     copyright (c) 1990 MSD                             *)
  306. (*                     Public Domain Object library                       *)
  307. (*                                                                        *)
  308. (*   Object:  TDateView                                                   *)
  309. (*                Same as TClockView, except displays the date            *)
  310. (*                                                                        *)
  311. (*   Object:  TPushButton                                                 *)
  312. (*                Same as TButton, except button "Show" press by keyboard *)
  313. (*                                                                        *)
  314. (*   Object:  TNum_Box                                                    *)
  315. (*                An editable number only entry box - configurable        *)
  316. (*                                                                        *)
  317. (*   Object:  TLinked_Dialog                                              *)
  318. (*                A normal dialog which handles cursor links to other     *)
  319. (*                items                                                   *)
  320. (*                                                                        *)
  321. (*   Func:    FormatDate                                                  *)
  322. (*                Formats a date into a string                            *)
  323. (*                                                                        *)
  324. (**************************************************************************)
  325.  
  326. {$F+,O+,S-,D+}
  327.  
  328. Interface
  329.  
  330. Uses Crt, Dos, Objects, Views, Dialogs, Drivers;
  331.  
  332. (*   Constents for Linked_Dialog   *)
  333.  
  334. Const        DLink_Left                =        1 ;
  335.                 DLink_Right                =        2 ;
  336.                 DLink_Up                =        3 ;
  337.                 DLink_Down                =        4 ;
  338.                 DLink_Spare1        =        5 ;
  339.                 DLink_Spare2        =        6 ;
  340.  
  341. Type
  342.  
  343. (**************************************************************************)
  344. (*                                                                        *)
  345. (*                        Object: TDateView                               *)
  346. (*                                                                        *)
  347. (*  Desc: TDateView is a static text object of the date, in a formated    *)
  348. (*        string, usually placed on the status or menu lines.             *)
  349. (*                                                                        *)
  350. (*        Format:  Sun  Dec 16, 1990                                      *)
  351. (*                                                                        *)
  352. (*        This format can be altered by changing Function FormatDate.     *)
  353. (*                                                                        *)
  354. (*  Init: Initialization is done by supply a TRect to the INIT method.    *)
  355. (*                                                                        *)
  356. (*  Note: The UPDATE method checks to see if the Day-of-Week value still  *)
  357. (*        matches the system Day-of-Week, and updates it's view if they   *)
  358. (*        don't match.  An occasional call to TDateView.UPDATE will keep  *)
  359. (*        your date indicator up to date.                                 *)
  360. (*                                                                        *)
  361. (**************************************************************************)
  362.  
  363.         PDateView = ^TDateView;
  364.         TDateView = Object(TView)
  365.                                         DateStr: string[19];
  366.                                         Last_DOW: Word;
  367.                                         Constructor Init(var Bounds: TRect);
  368.                                         Procedure Draw; virtual;
  369.                                         Procedure Update; virtual;
  370.                                 End;
  371.  
  372. (**************************************************************************)
  373. (*                                                                        *)
  374. (*                        Object: TPushButton                             *)
  375. (*                                                                        *)
  376. (*  Desc: TPushButton is a TButton except that it indicates being         *)
  377. (*        pressed from the keyboard.                                      *)
  378. (*                                                                        *)
  379. (*  Note: You may wish to adjust with the delay values in the             *)
  380. (*        TPushButton.Press method to suit your taste.                    *)
  381. (*                                                                        *)
  382. (*        See TButton for method descriptions.                            *)
  383. (*                                                                        *)
  384. (**************************************************************************)
  385.  
  386.   PPushButton        =        ^TPushButton;
  387.   TPushButton        =        Object(Tbutton)
  388.                                                 Procedure Press ;        Virtual ;
  389.                                         End;
  390.  
  391. (**************************************************************************)
  392. (*                                                                        *)
  393. (*                        Object: TNum_Box                                *)
  394. (*                                                                        *)
  395. (*  Desc: TInt_Box is a number only input box with an adjustable number   *)
  396. (*        of digits before and after the decimal point.                   *)
  397. (*                                                                        *)
  398. (*        It can be flagged not to accept negative numbers if desired.    *)
  399. (*                                                                        *)
  400. (*  Init: Initialization is done by providing your desired configuration  *)
  401. (*        to TNum_Box.Init.                                               *)
  402. (*                                                                        *)
  403. (*        TNum_Box.Init(                                                  *)
  404. (*            Loc       -     TPoint with location for num                *)
  405. (*            MaxWh     -     Integer with #digits before the decimal     *)
  406. (*                            point                                       *)
  407. (*            MaxDs     -     Integer with #digits after the decimal      *)
  408. (*                            point                                       *)
  409. (*            NegOk     -     Boolean.  True if neg values allowed        *)
  410. (*            Deflt     -     Extended floating point with default value  *)
  411. (*                     )                                                  *)
  412. (*                                                                        *)
  413. (*  Box width =   MaxWh +                                                 *)
  414. (*                MaxDs + 1 ( if MaxDs > 0 ) +                            *)
  415. (*                1 if Negok                                              *)
  416. (*                                                                        *)
  417. (*  To read the value back, simply access the Curr_Val variable for the   *)
  418. (*  TNum_Box.  It is an extended floating point varaible, so you should   *)
  419. (*  convert it to the desired precision.                                  *)
  420. (*                                                                        *)
  421. (*  Note:  A call to TNum_Box.Update_Val "Locks" the edited number into   *)
  422. (*         the curr_val field, loading the default value if no number has *)
  423. (*         been entered.                                                  *)
  424. (*                                                                        *)
  425. (**************************************************************************)
  426.  
  427.         PNum_Box    =        ^TNum_Box;
  428.         TNum_Box    =        Object        ( TView )
  429.                                                 Max_Whole        :        Integer ;
  430.                                                 Max_Decs        :        Integer ;
  431.                                                 Max_Len                :        Integer ;
  432.                                                 Neg_Ok      :   Boolean ;
  433.                                                 Default_val        :        Extended ;
  434.                                                 Num_Str                :        String[24] ;
  435.                                                 Curr_Val        :        Extended ;
  436.                                                 Dec_Pos                :        Integer ;
  437.                                                 First_Char        :        Boolean ;
  438.  
  439.                                                 Constructor Init( Loc        :        TPoint ;
  440.                                                                                   MaxWh :        Integer ;
  441.                                                                                   MaxDs :        Integer ;
  442.                                                                                   NegOk :         Boolean ;
  443.                                                                                   Dflt        :        Extended );
  444.                                                 Procedure Draw;        Virtual;
  445.                                                 Procedure HandleEvent( Var Event:TEvent ); Virtual;
  446.                                                 Procedure SetState( AState:Word; Enable:Boolean);
  447.                                                         Virtual;
  448.                                                 Procedure Add_Digit( Charcode : Char );        Virtual;
  449.                                                 Procedure Do_Edit( Keycode : Word ); Virtual;
  450.                                                 Procedure Update_Value;
  451.                                         End;
  452.  
  453. (*  Record used by TLinked_Dialog  *)
  454.  
  455.                 DLink_Record        =        Record
  456.                                                                 Item                :        Pointer ;
  457.                                                                 Left_Link        :        Pointer ;
  458.                                                                 Right_Link        :        Pointer ;
  459.                                                                 Up_Link                :        Pointer ;
  460.                                                                 Down_Link        :        Pointer ;
  461.                                                                 Spare1_Link        :        Pointer ;
  462.                                                                 Spare2_Link        :        Pointer ;
  463.                                                         End;
  464.  
  465. (*  Object for TLinked_Dialog's collection  *)
  466.  
  467.                 PLink_Item                =        ^TLink_Item ;
  468.                 TLink_Item                =        Object
  469.                                                                 Item                :        Pointer ;
  470.                                                                 Pointers        :        Array[1..6] of Pointer ;
  471.                                                                 Constructor Init( Link_Rec : DLink_Record );
  472.                                                                 Procedure Add_Link( Link_Direc : Integer ;
  473.                                                                                                         Link : Pointer );
  474.                                                         End;
  475.  
  476. (*  TLinked_Dialog's collection of links  *)
  477.  
  478.                 PLinked_List        =        ^TLinked_List ;
  479.                 TLinked_List        =        Object( TCollection )
  480.                                                                 Function Search( key : Pointer ) : Integer ;
  481.                                                         End;
  482.  
  483. (**************************************************************************)
  484. (*                                                                        *)
  485. (*                        Object: TLinked_Dialog                          *)
  486. (*                                                                        *)
  487. (*  Desc: TLinked_Dialog is a variation of a standard dialog which        *)
  488. (*        allows for improved cursor movement between items.              *)
  489. (*                                                                        *)
  490. (*        You can define which objects to "Link" to on the right, left,   *)
  491. (*        above and below.  These objects are focused by use of the       *)
  492. (*        cursor keys.                                                    *)
  493. (*                                                                        *)
  494. (*        Two spare links are defined for item use ( such as switching    *)
  495. (*        to a certain box once a button is pressed. )                    *)
  496. (*                                                                        *)
  497. (*  Init: Initialization is identical to TDialog's init.  Refer to the    *)
  498. (*        Turbo Vision manual for details.                                *)
  499. (*                                                                        *)
  500. (*  Inserting an item is identical to a normal TDialog.Insert. When an    *)
  501. (*  item is inserted into a TLinked_Dialog, a record is created for       *)
  502. (*  tracking links.                                                       *)
  503. (*                                                                        *)
  504. (*                             Defining a Link                            *)
  505. (*                                                                        *)
  506. (*  Once you have inserted all items into your dialog, links are created  *)
  507. (*  to other items using TLinked_Dialog.Setlink.                          *)
  508. (*                                                                        *)
  509. (*  TLinked_Dialog.Setlink(                                               *)
  510. (*       P          -    PView or descendant.                             *)
  511. (*                       This is a pointer to the item you wish to add    *)
  512. (*                       the link to.                                     *)
  513. (*       Link_Direc -    Integer with link direction.                     *)
  514. (*                       This should be one of the following constants:   *)
  515. (*                             DLink_Up     :   Up                        *)
  516. (*                             DLink_Down   :   Down                      *)
  517. (*                             DLink_Right  :   Right                     *)
  518. (*                             DLink_Left   :   Left                      *)
  519. (*                             DLink_Spare1 :   Spare 1                   *)
  520. (*                             DLink_Spare2 :   Spare 2                   *)
  521. (*       Link       -    A pointer to the item you want to link to        *)
  522. (*       )                                                                *)
  523. (*                                                                        *)
  524. (*                           Accesing a link                              *)
  525. (*                                                                        *)
  526. (*  Items within a dialog can switch to a linked item by calling:         *)
  527. (*                                                                        *)
  528. (*  TLinked_Dialog.Select_link(                                           *)
  529. (*       Direc      -    Integer with link direction.                     *)
  530. (*       )                                                                *)
  531. (*                                                                        *)
  532. (**************************************************************************)
  533.  
  534.                 PLinked_Dialog        =   ^TLinked_Dialog ;
  535.                 TLinked_Dialog        =        Object( TDialog )
  536.                                                                 Link_List        :        TLinked_List ;
  537.                                                                 Constructor Init(var Bounds: TRect;
  538.                                                                                                  ATitle: TTitleStr);
  539.                                                                 Procedure Insert(P: PView); Virtual;
  540.                                                                 Procedure Set_Link( P: PView ;
  541.                                                                                                         Link_Direc : Integer ;
  542.                                                                                                         Link : Pointer );
  543.                                                                 Procedure HandleEvent( Var Event : TEvent );
  544.                                                                         Virtual;
  545.                                                                 Procedure Select_Link( Direc : Integer );
  546.                                                         End;
  547.  
  548.  
  549. (**************************************************************************)
  550. (*                                                                        *)
  551. (*                      Function: FormatDate                              *)
  552. (*                                                                        *)
  553. (*  Desc:  The format date function used by TDateView, made public for    *)
  554. (*         other possible uses.                                           *)
  555. (*                                                                        *)
  556. (**************************************************************************)
  557.  
  558. Function FormatDate( Year , Month , Day , DOW : Word ): String;
  559.  
  560. Implementation
  561.  
  562. (**************************************************************************)
  563. (*                                                                        *)
  564. (*                        Object: TDateView                               *)
  565. (*                                                                        *)
  566. (**************************************************************************)
  567.  
  568. Constructor TDateView.Init(var Bounds: TRect);
  569. Begin
  570.         TView.Init(Bounds);
  571.         DateStr := '';
  572.         LAST_DOW := 8 ;     (*  Force an update!  *)
  573. End;
  574.  
  575.  
  576. (* Draw the TDateView object *)
  577.  
  578. Procedure TDateView.Draw;
  579. Var
  580.         B: TDrawBuffer;
  581.         C: Byte;
  582. Begin
  583.         C := GetColor(2);
  584.         MoveChar(B, ' ', C, Size.X);
  585.         MoveStr(B, DateStr, C);
  586.         WriteLine(0, 0, Size.X, 1, B);
  587. End;
  588.  
  589. (* Verify the TDateView object is up to date *)
  590. (* Redisplaying it if it needs updating      *)
  591.  
  592. Procedure TDateView.Update;
  593. Var Year, Month, Day, DOW : word;
  594. Begin
  595.         GetDate( Year , Month , Day , Dow );
  596.         If (DOW <> LAST_DOW) then
  597.         Begin
  598.                 DateStr := FormatDate( Year , Month , Day , DOW );
  599.                 DrawView;
  600.                 LAST_DOW := DOW ;
  601.         End;
  602. End;
  603.  
  604. (**************************************************************************)
  605. (*                                                                        *)
  606. (*                        Object: TPushButton                             *)
  607. (*                                                                        *)
  608. (**************************************************************************)
  609.  
  610. Procedure TPushButton.Press;
  611. Begin
  612.         DrawState(TRUE);        (*  Draw Button "Pressed"  *)
  613.         Delay(150);
  614.         DrawState(FALSE);        (*  Draw Button "Released" *)
  615.         Delay(50);
  616.         TButton.Press;
  617. End;
  618.  
  619. (**************************************************************************)
  620. (*                                                                        *)
  621. (*                        Object: TNum_Box                                *)
  622. (*                                                                        *)
  623. (**************************************************************************)
  624.  
  625. Constructor TNum_Box.Init( Loc : TPoint ; MaxWh, MaxDs : Integer ;
  626.                                                    NegOk : Boolean ;  Dflt : Extended );
  627. Var        R                :        TRect ;
  628.         X                :        Integer ;
  629.         Wrk_Str :        String ;
  630.  
  631. Begin
  632.  
  633.         Wrk_Str := '' ;
  634.         If ( NegOk ) then
  635.                 Wrk_Str := ' ' ;
  636.         For X := 1 to MaxWh do
  637.                 Wrk_Str := Wrk_Str + ' ' ;
  638.  
  639.         If ( MaxDs > 0 ) then
  640.         Begin
  641.                 Wrk_Str := Wrk_Str + '.';
  642.                 For X := 1 to MaxDs do
  643.                         Wrk_Str := Wrk_Str + ' ' ;
  644.         End;
  645.         R.Assign( Loc.X , Loc.Y , Loc.X + Length( Wrk_Str ) , Loc.Y + 1 );
  646.         TView.Init( R ) ;
  647.  
  648.         Num_Str := Wrk_Str ;
  649.  
  650.         Neg_Ok := NegOk ;
  651.         Max_Whole := MaxWh ;
  652.         Max_Decs := MaxDs ;
  653.  
  654.         Max_Len := Length( Num_Str );
  655.  
  656.         Options := Options OR ofSelectable ;
  657.  
  658.         Default_Val := Dflt ;
  659.         Curr_Val := Dflt ;
  660.         Dec_Pos := Pos( '.' , Num_Str );
  661.  
  662.         If ( Dec_Pos < 1 ) then
  663.                 Dec_Pos := Max_Len + 1 ;
  664.  
  665.  
  666.         Cursor.X := Dec_Pos - 2;
  667.  
  668.         First_Char := True ;
  669.         ShowCursor;
  670. End;
  671.  
  672. (*  Draw the TNum_Box on the view.  *)
  673. (*  Color depends on the state of   *)
  674. (*  the object.                     *)
  675.  
  676. Procedure TNum_Box.Draw;
  677. Var        Buff : TDrawBuffer ;
  678.         Colr : Word;
  679. Begin
  680.         Colr := GetColor(19);
  681.         If GetState(sfFocused) then
  682.                 If First_Char then
  683.                         Colr := GetColor(20)
  684.                 else
  685.                         Colr := GetColor(22);
  686.  
  687.         MoveChar( Buff,' ',Colr, Size.X);
  688.         MoveStr( Buff,Num_Str,0);
  689.         Writeline(0,0,Size.X,1,Buff);
  690.  
  691. End;
  692.  
  693. (*  Updated SetState to watch for changes in the  *)
  694. (*  selected and focused flags.                   *)
  695.  
  696. Procedure TNum_Box.SetState(AState: Word; Enable: Boolean);
  697. Begin
  698.         TView.SetState(AState, Enable);
  699.         If ( AState = sfFocused ) then
  700.                 Draw ;
  701.         If ( AState = sfFocused ) And ( Enable ) then
  702.                 First_Char := TRUE ;
  703. End;
  704.  
  705. (*  HandleEvent, routing keystrokes  *)
  706.  
  707. Procedure TNum_Box.HandleEvent( Var Event : TEvent );
  708. Var        NextCmd: TEvent;
  709.         test:PEvent;
  710. Begin
  711.         TView.HandleEvent( Event );
  712.         If Event.What = evKeydown then
  713.         Begin
  714.                 Case ( Event.Charcode ) of
  715.                         #00                :   Begin
  716.                                                 End;
  717.                         #08                :        Begin
  718.                                                         Do_Edit( Event.keyCode );
  719.                                                         ClearEvent( Event );
  720.                                                 End;
  721.                         #13                :        Begin
  722.                                                         ClearEvent( Event );
  723.                                                         Update_Value ;
  724.                                                 End;
  725.                         '0'..'9':        Begin
  726.                                                         Add_Digit( Event.Charcode );
  727.                                                         ClearEvent( Event );
  728.                                                 End;
  729.                         '.','-':        Begin
  730.                                                         Add_Digit( Event.Charcode );
  731.                                                         ClearEvent( Event );
  732.                                                 End;
  733.                         End;
  734.         End;
  735. End;
  736.  
  737. (*  Perform normal charector addition to the number string  *)
  738.  
  739. Procedure TNum_Box.Add_Digit( Charcode : Char );
  740. Var        X                        :        Integer ;
  741.         First_Dig        :        Integer ;
  742. Begin
  743.  
  744.         If ( First_Char ) then
  745.         Begin
  746.                 For X := 1 to Length( Num_Str ) do
  747.                         If (Num_Str[X]<>'.') then
  748.                                 Num_Str[X]:=' ';
  749.  
  750.                 First_Char := False ;
  751.                 Cursor.X := Dec_Pos - 2;
  752.                 ShowCursor;
  753.         End;
  754.  
  755.         If Neg_Ok then
  756.                 First_Dig := 2
  757.         else
  758.                 First_Dig := 1;
  759.  
  760.         If ( Cursor.X < Dec_Pos ) then
  761.         Case ( Charcode ) of
  762.                 '0'..'9'        :        If Not( Num_Str[ First_Dig ] IN ['0'..'9']) then
  763.                                                 Begin
  764.                                                         For X := 1 to Cursor.X do
  765.                                                                 Num_Str[X] := Num_Str[X+1] ;
  766.                                                         Num_Str[ Cursor.X + 1 ] := Charcode ;
  767.                                                 End;
  768.                 '-'                        :        Begin
  769.                                                         If (Neg_Ok) then
  770.                                                         Begin
  771.                                                                 if (Num_Str[ Cursor.X + 1 ] = ' ') then
  772.                                                                         Num_Str[ Cursor.X + 1 ] := '-'
  773.                                                         End;
  774.                                                 End;
  775.                 '.'                        :        Begin
  776.                                                         If (Max_Decs>0) and ( Cursor.X < Dec_Pos ) then
  777.                                                         Begin
  778.                                                                 Cursor.X := Dec_Pos ;
  779.                                                                 ShowCursor;
  780.                                                         End;
  781.                                                 End;
  782.         End
  783.         else
  784.         Case ( Charcode ) of
  785.                 '0'..'9'        :        Begin
  786.                                                         If ( Cursor.X < ( Max_Len - 1 )) then
  787.                                                         Begin
  788.                                                                 Num_Str[Cursor.X+1] := Charcode ;
  789.                                                                 Inc( Cursor.X );
  790.                                                                 ShowCursor;
  791.                                                         End
  792.                                                         else
  793.                                                                 if Num_Str[Cursor.X+1] = ' ' then
  794.                                                                         Num_Str[Cursor.X+1] := Charcode ;
  795.                                                 End;
  796.         End;
  797.  
  798.         Draw;
  799. End;
  800.  
  801. (*  Perform any editing on the number string  *)
  802. (*  ( Only the <Backspace> key is currently   *)
  803. (*  supported ).                              *)
  804.  
  805. Procedure TNum_Box.Do_Edit( Keycode : Word );
  806. Var        X                        :        Integer ;
  807. Begin
  808.         First_Char := False ;
  809.         If ( Dec_Pos = 0 ) or ( Cursor.X < Dec_Pos ) then
  810.         Begin
  811.                 If (Keycode = kbBack) then
  812.                 Begin
  813.                         For X := Cursor.X+1 downto 2 do
  814.                                 Num_Str[X] := Num_Str[X-1] ;
  815.                         Num_Str[ 1 ] := ' ' ;
  816.                 End;
  817.         End
  818.         else
  819.         Begin
  820.                 If (Keycode = kbBack) then
  821.                 Begin
  822.                         If Num_Str[Cursor.X+1] = ' ' then
  823.                         Begin
  824.                                 Dec( Cursor.X );
  825.                                 Num_Str[Cursor.X+1] := ' ';
  826.                         End
  827.                         else
  828.                                 Num_Str[Cursor.X+1] := ' ';
  829.  
  830.                         If Num_Str[ Cursor.X ] = '.' then
  831.                                 Cursor.X := Cursor.X - 2 ;
  832.                         ShowCursor;
  833.                 End;
  834.         End;
  835.  
  836.         Draw;
  837. End;
  838.  
  839. (* "Lock" the number string value in the box.     *)
  840. (* Use the default value if no number is present. *)
  841.  
  842. Procedure TNum_Box.Update_Value;
  843. Var Code        :        Integer ;
  844.         Work_str:        String[24];
  845. Begin
  846.         Work_Str := Num_Str ;
  847.         While (( Length( Work_Str )>0 ) and ( Work_Str[Length( Work_Str )] IN ['.',' '])) do
  848.                 Work_Str := Copy( Work_Str , 1 , length( Work_Str ) -1 );
  849.  
  850.         Code := 0 ;
  851.  
  852.         If ( Work_Str = '' ) then
  853.                 Curr_Val := Default_Val
  854.         else
  855.                 Val( Work_Str, Curr_Val , Code );
  856.         Str( Curr_Val:Max_Len:Max_Decs , Num_Str );
  857.  
  858.         Cursor.X := Max_Len - 1 ;
  859.         First_Char := True ;
  860.         Draw;
  861. End;
  862.  
  863. (**************************************************************************)
  864. (*                                                                        *)
  865. (*                        Object: TLink_Item                              *)
  866. (*                                                                        *)
  867. (*                 Used by TLinked_Dialog to track links                  *)
  868. (*                                                                        *)
  869. (**************************************************************************)
  870.  
  871. Constructor TLink_Item.Init( Link_Rec : DLink_Record );
  872. Begin
  873.         Item := Link_Rec.Item ;
  874.         With Link_Rec do
  875.         Begin
  876.                 Pointers[DLink_Left]        := Left_Link;
  877.                 Pointers[DLink_Right]        := Right_Link;
  878.                 Pointers[DLink_Up]                := Up_Link;
  879.                 Pointers[DLink_Down]         := Down_Link;
  880.                 Pointers[DLink_Spare1]        := Spare1_Link;
  881.                 Pointers[DLink_Spare2]        := Spare2_Link;
  882.         End;
  883. End;
  884.  
  885. Procedure TLink_Item.Add_Link( Link_Direc : Integer ; Link : Pointer );
  886. Begin
  887.         Pointers[ Link_Direc ] := Link ;
  888. End;
  889.  
  890. (**************************************************************************)
  891. (*                                                                        *)
  892. (*                        Object: TLink_List                              *)
  893. (*                                                                        *)
  894. (*                 Used by TLinked_Dialog to track links                  *)
  895. (*                                                                        *)
  896. (**************************************************************************)
  897.  
  898. Function TLinked_List.Search( Key : Pointer ) : Integer ;
  899. Var        X : Integer ;
  900.         Found : Boolean ;
  901.         Linked_Item : PLink_Item ;
  902. Begin
  903.         Search := -1 ;
  904.         Found := False ;
  905.         X := 0 ;
  906.         While ( X < Count ) AND ( NOT FOUND ) do
  907.         Begin
  908.                 Linked_Item := at( X );
  909.                 Found := Linked_Item^.Item = Key ;
  910.                 X := X + 1 ;
  911.         End;
  912.  
  913.         If ( Found ) then
  914.                 Search := X - 1 ;
  915. End;
  916.  
  917. (**************************************************************************)
  918. (*                                                                        *)
  919. (*                        Object: TLinked_Dialog                          *)
  920. (*                                                                        *)
  921. (**************************************************************************)
  922.  
  923. Constructor TLinked_Dialog.Init(var Bounds: TRect; ATitle: TTitleStr);
  924. Begin
  925.         TDialog.Init( Bounds , ATitle );
  926.         Link_List.Init(10, 5);
  927. End;
  928.  
  929. Procedure TLinked_Dialog.Insert(P: PView);
  930. Var        Linked_Item : PLink_Item ;
  931.         Blank_Rec : DLink_Record ;
  932. Begin
  933.         With Blank_Rec do
  934.         Begin
  935.                 Item := P ;
  936.                 Left_Link         := Nil ;
  937.                 Right_Link        := Nil ;
  938.                 Up_Link                := Nil ;
  939.                 Down_Link        := Nil ;
  940.                 Spare1_Link        := Nil ;
  941.                 Spare2_Link := Nil ;
  942.         End;
  943.         Linked_Item := New( PLink_Item , Init( Blank_Rec ) );
  944.         TDialog.Insert( P );
  945.         Link_List.Insert( Linked_Item );
  946. End;
  947.  
  948. Procedure TLinked_Dialog.Set_Link(P:PView;Link_Direc:Integer;Link:Pointer);
  949. Var        Linked_Item : PLink_Item ;
  950.         X : Integer ;
  951. Begin
  952.         X := Link_List.Search( P );
  953.         If ( X < 0 ) then
  954.                 Exit ;
  955.         Linked_Item := Link_List.at( X );
  956.         Linked_Item^.Pointers[ Link_Direc ] := Link ;
  957. End;
  958.  
  959. Procedure TLinked_Dialog.Select_Link( Direc : Integer );
  960. Var        X                : Integer ;
  961.         LL_Item        : PLink_Item ;
  962.         Item        : PView ;
  963. Begin
  964.         X := Link_List.Search( Current );
  965.         LL_Item := Link_List.at(X);
  966.         Item := LL_Item^.Pointers[ Direc ];
  967.         If ( Item <> Nil ) then
  968.                 Item^.Select ;
  969. End;
  970.  
  971. Procedure TLinked_Dialog.HandleEvent( Var Event : TEvent );
  972. Var        X                : Integer ;
  973.         LL_Item        : PLink_Item ;
  974.         Item        : PView ;
  975. Begin
  976.         TDialog.HandleEvent( Event );
  977.  
  978.         If ( Event.What = evKeydown ) then
  979.                 Case Event.keycode of
  980.                         kbUp        :        Begin
  981.                                                         Select_Link( DLink_Up );
  982.                                                         ClearEvent( Event );
  983.                                                 End;
  984.                         kbDown        :        Begin
  985.                                                         Select_Link( DLink_Down );
  986.                                                         ClearEvent( Event );
  987.                                                 End;
  988.                         kbRight        :        Begin
  989.                                                         Select_Link( DLink_Right );
  990.                                                         ClearEvent( Event );
  991.                                                 End;
  992.                         kbLeft        :        Begin
  993.                                                         Select_Link( DLink_Left );
  994.                                                         ClearEvent( Event );
  995.                                                 End;
  996.                 End;
  997. End;
  998.  
  999. (**************************************************************************)
  1000. (*                                                                        *)
  1001. (*                      Function: FormatDate                              *)
  1002. (*                                                                        *)
  1003. (**************************************************************************)
  1004.  
  1005. Function FormatDate( Year , Month , Day , DOW : Word ): String;
  1006. Const
  1007.         DAYS : Array[0..6] of String = ( 'Sun','Mon','Tue','Wed','Thu','Fri','Sat');
  1008.         MONTHS : Array[1..12] of String = ( 'Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
  1009. Var Work1,Work2 : String[4] ;
  1010. Begin
  1011.         Str( Day,Work1 );
  1012.         If ( Day < 10 ) then
  1013.         Work1 := '0' + Work1 ;
  1014.         Str( Year,Work2 );
  1015.         FormatDate := DAYS[DOW]+'  '+MONTHS[Month]+' '+Work1+', '+Work2;
  1016. End;
  1017.  
  1018. Begin
  1019. end.
  1020.  
  1021. {-----------------------    DEMO CODE --------------------- }
  1022.  
  1023. Program Example;
  1024.  
  1025. Uses Crt,App, Objects, Views, Dialogs, Drivers, Misc;
  1026.  
  1027. Type
  1028.         PMyApp                =        ^TMyApp ;
  1029.         TMyApp                =        Object( TApplication )
  1030.                                                 Constructor Init;
  1031.                                         End;
  1032.  
  1033. Var
  1034.         MyApp        :        TMyApp ;
  1035.         Dialog  :   PLinked_Dialog;
  1036.  
  1037.         Screen_Array        :        Array[1..70] of TNum_Box;
  1038.  
  1039. Procedure Build_Links;
  1040. Var        P        :        TPoint ;
  1041.         X,Y :        Integer ;
  1042.         N        :        Integer ;
  1043. Begin
  1044.  
  1045.         For N := 1 to 50 do
  1046.         Begin
  1047.                 P.Y := ( N - 1 ) DIV 10         + 8 ;
  1048.                 P.X := ( N - 1 ) MOD 10 * 4 + 20 ;
  1049.  
  1050.                 Screen_Array[N].Init( P , 3 , 0 , FALSE , N );
  1051.                 Screen_Array[N].Update_Value;
  1052.         End;
  1053.  
  1054.         For N := 1 to 8 do
  1055.         Begin
  1056.                 P.Y := ( N - 1 ) Div 3 * 2 + 8  ;
  1057.                 P.X := ( N - 1 ) Mod 3 * 4 + 60 ;
  1058.                 If ( N > 6 ) then
  1059.                         P.X := P.X + 4 ;
  1060.                 Screen_Array[N+50].Init( P , 3 , 0 , FALSE , N+50 );
  1061.                 Screen_Array[N+50].Update_Value;
  1062.         End;
  1063.  
  1064.         P.Y := 6 ;
  1065.  
  1066. (* Initialize 5 floating point boxes *)
  1067.  
  1068.         For N := 1 to 5 do
  1069.         Begin
  1070.                 P.X := ( N * 12 ) ;
  1071.                 Screen_Array[N+58].Init( P , 4 , 2 , True , N+58 );
  1072.         End;
  1073.  
  1074. (* Insert all boxes before setting links! *)
  1075.  
  1076.         For N := 1 to 63 do
  1077.                 Dialog^.Insert( @Screen_Array[N] );
  1078.  
  1079.         For N := 1 to 50 do
  1080.         Begin
  1081.                 if ( N MOD 10 ) <> 1 then
  1082.                         Dialog^.Set_Link(@Screen_array[N],DLink_Left ,@Screen_array[N-1]);
  1083.                 if ( N MOD 10 ) <> 0 then
  1084.                         Dialog^.Set_Link(@Screen_array[N],DLink_Right,@Screen_array[N+1]);
  1085.                 if ( N > 10 ) then
  1086.                         Dialog^.Set_Link(@Screen_array[N],DLink_Up   ,@Screen_array[N-10])
  1087.                 else
  1088.                         Dialog^.Set_Link(@Screen_array[N],DLink_Up   ,@Screen_array[59]);
  1089.  
  1090.                 if ( N <41 ) then
  1091.                         Dialog^.Set_Link(@Screen_array[N],DLink_Down ,@Screen_array[N+10]);
  1092.  
  1093.                 if ( N=10 ) or ( N=20 ) then
  1094.                         Dialog^.Set_Link(@Screen_array[N],DLink_Right,@Screen_array[51]);
  1095.  
  1096.                 if ( N=30 ) or ( N=40 ) then
  1097.                         Dialog^.Set_Link(@Screen_array[N],DLink_Right,@Screen_array[54]);
  1098.         End;
  1099.  
  1100.         Dialog^.Set_Link(@Screen_array[50],DLink_Right,@Screen_array[57]);
  1101.  
  1102.         Dialog^.Set_Link(@Screen_array[51],DLink_Left ,@Screen_array[10]);
  1103.         Dialog^.Set_Link(@Screen_array[51],DLink_Right,@Screen_array[52]);
  1104.         Dialog^.Set_Link(@Screen_array[51],DLink_Down ,@Screen_array[54]);
  1105.  
  1106.         Dialog^.Set_Link(@Screen_array[52],DLink_Left ,@Screen_array[51]);
  1107.         Dialog^.Set_Link(@Screen_array[52],DLink_Right,@Screen_array[53]);
  1108.         Dialog^.Set_Link(@Screen_array[52],DLink_Down ,@Screen_array[55]);
  1109.  
  1110.         Dialog^.Set_Link(@Screen_array[53],DLink_Left ,@Screen_array[52]);
  1111.         Dialog^.Set_Link(@Screen_array[53],DLink_Down ,@Screen_array[56]);
  1112.  
  1113.         Dialog^.Set_Link(@Screen_array[54],DLink_Left ,@Screen_array[30]);
  1114.         Dialog^.Set_Link(@Screen_array[54],DLink_Right,@Screen_array[55]);
  1115.         Dialog^.Set_Link(@Screen_array[54],DLink_Down ,@Screen_array[57]);
  1116.         Dialog^.Set_Link(@Screen_array[54],DLink_Up   ,@Screen_array[51]);
  1117.  
  1118.         Dialog^.Set_Link(@Screen_array[55],DLink_Left ,@Screen_array[54]);
  1119.         Dialog^.Set_Link(@Screen_array[55],DLink_Right,@Screen_array[56]);
  1120.         Dialog^.Set_Link(@Screen_array[55],DLink_Down ,@Screen_array[57]);
  1121.         Dialog^.Set_Link(@Screen_array[55],DLink_Up   ,@Screen_array[52]);
  1122.  
  1123.         Dialog^.Set_Link(@Screen_array[56],DLink_Left ,@Screen_array[55]);
  1124.         Dialog^.Set_Link(@Screen_array[56],DLink_Down ,@Screen_array[58]);
  1125.         Dialog^.Set_Link(@Screen_array[56],DLink_Up   ,@Screen_array[53]);
  1126.  
  1127.         Dialog^.Set_Link(@Screen_array[57],DLink_Left ,@Screen_array[50]);
  1128.         Dialog^.Set_Link(@Screen_array[57],DLink_Right,@Screen_array[58]);
  1129.         Dialog^.Set_Link(@Screen_array[57],DLink_Up   ,@Screen_array[55]);
  1130.  
  1131.         Dialog^.Set_Link(@Screen_array[58],DLink_Left ,@Screen_array[57]);
  1132.         Dialog^.Set_Link(@Screen_array[58],DLink_Up   ,@Screen_array[56]);
  1133.  
  1134.         For N := 59 to 63 do
  1135.         Begin
  1136.                 if ( N > 59 ) then
  1137.                         Dialog^.Set_Link(@Screen_array[N],DLink_Left ,@Screen_array[N-1]);
  1138.                 if ( N < 63 ) then
  1139.                         Dialog^.Set_Link(@Screen_array[N],DLink_Right,@Screen_array[N+1]);
  1140.                 Dialog^.Set_Link(@Screen_array[N],DLink_Down,@Screen_array[1]);
  1141.         End;
  1142. End;
  1143.  
  1144. Procedure Do_Dialog;
  1145. Var        R                :        TRect ;
  1146.         TP                :        TPoint ;
  1147.         N                :        Integer ;
  1148.         Button        :        PButton ;
  1149. Begin
  1150.  
  1151.         R.Assign( 0 , 10 , 80 , 24 );
  1152.         Dialog := New( PLinked_Dialog , Init( R , 'Linked Dialog Example' ));
  1153.         Dialog^.SetState(sfShadow,False );
  1154.  
  1155.         Build_Links;
  1156.  
  1157.         R.Assign( 5 , 8 , 15 , 10 );
  1158.         Button := New(PPushButton,Init(R,'~P~ush',cmOk,bfDefault));
  1159.         Dialog^.Insert( Button );
  1160.  
  1161.         R.Assign( 5 , 11 , 15 , 13 );
  1162.         Button := New(PPushButton,Init(R,'~E~xit',cmQuit,bfDefault));
  1163.         Dialog^.Insert( Button );
  1164.  
  1165.         Dialog^.Set_Link(Button,DLink_Right,@Screen_array[1]);
  1166.  
  1167.         MyApp.Insert( Dialog );
  1168.  
  1169. End;
  1170.  
  1171.  
  1172. Constructor TMyApp.Init;
  1173. Begin
  1174.         TApplication.Init ;
  1175.         Do_Dialog;
  1176. End;
  1177.  
  1178. Begin
  1179.         ClrScr;
  1180.         MyApp.Init ;
  1181.         MyApp.Run ;
  1182.         MyApp.Done ;
  1183. End.